package progarbre;

import exprarbre.ASAIdent;
import instrarbre.ASABloc;
import instrarbre.ASAInstr;
import instrarbre.ReturnException;
import java.util.ArrayList;
import java.util.HashMap;
import javax.swing.JTextArea;

public class ASAFonction {

    private String label;
    private ArrayList<ASAIdent> parameters;
    private ASAInstr instruction;

    protected ASAFonction(String label, ArrayList<ASAIdent> parameters) {
        if (label == null) {
            throw new NullPointerException("label");
        }
        if (label.isEmpty()) {
            throw new IllegalArgumentException("label");
        }
        if (parameters == null) {
            throw new NullPointerException("parameters");
        }
        this.label = label.toUpperCase();
        this.parameters = parameters;
        this.instruction = new ASABloc();
    }

    public ASAFonction(String label, ArrayList<ASAIdent> parameters, ASAInstr instruction) {
        this(label, parameters);
        if (instruction == null) {
            throw new NullPointerException("instruction");
        }
        if (!(instruction instanceof ASABloc)) {
            throw new IllegalArgumentException("instruction");
        }
        this.instruction = instruction;
    }

    public ASAInstr getInstr() {
        return instruction;
    }

    public String getLabelExplorateur() {
        return label;
    }

    public String notationExplorateur() {
        return notationExplorateur("");
    }

    public int getNbDeclare() {
        return instruction.getNbDeclare() + parameters.size();
    }

    public int getNbParametre() {
        return parameters.size();
    }

    private String notationExplorateur(String prefixe) {
        String res = prefixe + getLabelExplorateur() + " (";
        for (ASAIdent parameter : parameters) {
            res += parameter.getLabelExplorateur() + ", ";
        }
        if (res.contains(", ")) {
            res = res.substring(0, res.length() - 2);
        }
        res += ")\n";
        res += instruction.notationExplorateur();
        return res;
    }

    public void interpreter() {
        try {
            instruction.interpreter(initAffectation());
        }
        catch (ReturnException e) {
        }
    }

    public void interpreter(HashMap<String, Integer> affectation) {
        instruction.interpreter(affectation);
    }

    private HashMap<String, Integer> initAffectation() {
        HashMap<String, Integer> affectation = new HashMap<String, Integer>();
        int pointeur = ASAProg.getBottom() + 1;
        for (ASAIdent ident : parameters) {
            affectation.put(ident.getLabelExplorateur(), pointeur++);
        }
        return affectation;
    }

    public void setView(JTextArea area) {
        if (instruction != null) {
            instruction.setView(area);
        }
    }
}